// Created by Laurent Mignonneau
// Advanced course example
// May 2011

// works with a 7x5 dot matrix display

// columns and rows are connected as follows
byte col[5] = {2, 3, 4, 5, 6};
byte row[7] = {7, 8, 9, 10, 11, 12, 13};

// six motifs is the original render view
byte motif[5][7]={   
   {0, 0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, 0}};

byte gameScreen[7][5] = {
   {0, 0, 0, 0, 0},
   {1, 0, 1, 0, 1},
   {1, 0, 1, 0, 0},
   {1, 1, 1, 0, 1},
   {1, 0, 1, 0, 1},
   {1, 0, 1, 0, 1},
   {0, 0, 0, 0, 0}};
   

long previousMillis = 0; 
long interval = 50; // Ein Interval von 50ms entspricht 20Frames per second
int frameCounter = 0;

int index;
byte valueController = 1;
boolean debug = false; // If you want to debug your code, change it to true and check the Serial Monitor



/////////////////////////////////////////////////////
// SETUP THIS WHOLE SHIT
void setup() {                
  // initialize the digital pin as outputs.
  pinMode(2, OUTPUT);     
  pinMode(3, OUTPUT);     
  pinMode(4, OUTPUT);     
  pinMode(5, OUTPUT);     
  pinMode(6, OUTPUT);     
  pinMode(7, OUTPUT);     
  pinMode(8, OUTPUT);     
  pinMode(9, OUTPUT);     
  pinMode(10, OUTPUT);     
  pinMode(11, OUTPUT);     
  pinMode(12, OUTPUT);     
  
  
  // only one col at a time (here LOW means that the column is making the row LEDs visible !)
  digitalWrite(2, HIGH);   // set col LED off
  digitalWrite(3, HIGH);   // set col LED off
  digitalWrite(4, HIGH);   // set col LED off
  digitalWrite(5, HIGH);   // set col LED off
  digitalWrite(6, HIGH);   // set col LED off

  // 7 pixels visible in one col
  digitalWrite(7, HIGH);   // set the LED on
  digitalWrite(8, HIGH);   // set the LED on
  digitalWrite(9, HIGH);   // set the LED on
  digitalWrite(10, HIGH);   // set the LED on
  digitalWrite(11, HIGH);   // set the LED on
  digitalWrite(12, HIGH);   // set the LED on
  digitalWrite(13, HIGH);   // set the LED on
  
  Serial.begin(9600);

}

void loop() {
  
  ////////////////////////////////////////////////
  // Game Logic
  unsigned long currentMillis = millis();
  
  // Check if a new Frame is reached
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 
    frameCounter++;
    
   // Only each 5th frame executes this code
   if(frameCounter > 5) {
	 frameCounter = 0;
	 renderGameScreen();
         // Look at the data of GameScreen on the Serial Monitor
         if(debug) debugGameScreen();
    }
    
  } // End Timer intervall 
  
  
  ////////////////////////////////////////////////
  // Map the game data to the screen
  // Render the data directly for the hardware
  renderHardware();
  if(debug) debugHardwareScreen();  
}
/////////////////////////////////////////////////////////////////////////
////////////////// Functions ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
void gamerInteraction()
{
  // Here use your sensor inputs and interaction stuff
  valueController = byte(analogRead(A0) / 340);
  if(debug) Serial.println(valueController);
}



//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////

// Rotate and prepare the potrait format of the screen to landscape
void renderGameScreen() 
{
  int gameY,gameX;
  int targetX = 0;
  int targetY = 0;
  
  for(gameX=0;gameX < 5;gameX++)
  {
    for(gameY=0;gameY < 7;gameY++)
    {
      motif[targetY][targetX] = gameScreen[gameY][gameX];
      targetX++;
    }
    targetX = 0;
    targetY++;
  } 
}

//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// display the Game Graphic on the Hardware Screen
void renderHardware()
{
  int cl;
  // each column is scanned one at a time
  for(cl=0; cl < 5; cl++)
  { 
     //turn ON the selected column first
     digitalWrite(col[cl], LOW);
     // then find out if each pixel is ON or OFF in the row
     for(index=0;index<7;index++)
     {
       if(motif[cl][index] < 1) digitalWrite(row[index], LOW);
       else digitalWrite(row[index], HIGH);
     }
     // slows down the loop a bit to get more light output.
     // if you need to read sensors, you can do it here instead this delay
     gamerInteraction();
     delay(1);
     // now turn OFF the current column
     digitalWrite(col[cl], HIGH);
     // well, that's it
     
  } 
}


///////////////////////////////////////////////////////////
// This functions makes your life easier for finding errors. 
// Output is generated for the Serial Monitor
void debugGameScreen()
{
  Serial.println("--- Game Screen ---");
  for(int y = 6; y >= 0; y--) {
    Serial.println("");
    for(int x = 0; x < 5; x++) {
      if(gameScreen[y][x] > 0)      
        Serial.print('1');
      else
        Serial.print('0');
    }
  }
  Serial.println("");
  Serial.println("-------------");
}


void debugHardwareScreen()
{
  Serial.println("--- Hardware Screen ---");
  for(int y = 0; y < 5; y++) {
    Serial.println("");
    for(int x = 0; x < 7; x++) {
      if(motif[y][x] > 0)      
        Serial.print('1');
      else
        Serial.print('0');
    }
  }
  Serial.println("");
  Serial.println("-------------");
}

